/**
 * App 更新服务
 */
import { Injectable, OnInit } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Platform, AlertController, LoadingController, ModalController } from '@ionic/angular';
import { GlobalService } from './global.service';
import { FileTransfer, FileTransferObject } from '@ionic-native/file-transfer/ngx';
import { FileOpener } from '@ionic-native/file-opener/ngx';
import { CacheService } from '@services/cache.service';

import { Observable } from 'rxjs';
import { CodePush, SyncStatus, InstallMode, InstallOptions } from '@ionic-native/code-push/ngx';
import { DEBUG, CODE_PUSH_DEPLOYMENT_KEY } from '../codepush.constants';
import { AppUpdate } from '@ionic-native/app-update/ngx';
import { File } from '@ionic-native/file/ngx';
import { UpdateModal } from '@modals/update-modal/update-modal';
import { AppVersion } from '@ionic-native/app-version/ngx';

declare var window;

@Injectable()
export class UpdateService implements OnInit {
  headers: HttpHeaders = new HttpHeaders({
    'Content-Type': 'application/x-www-form-urlencoded',
  });

  Alert: any;
  alert: any;
  loading: any;
  updateModal: any;
  AppVersion: any;

  load: any;   // 热更新加载

  constructor(
    public platform: Platform,
    public _global: GlobalService,
    public loadingCtrl: LoadingController,
    public http: HttpClient,
    public transfer: FileTransfer,
    private fileOpener: FileOpener,
    private codePush: CodePush,
    public alertController: AlertController,
    public cache: CacheService,
    public appUpdate: AppUpdate,
    public file: File,
    public modalCtrl: ModalController,
    public appVersion: AppVersion,
  ) {

  }

  ngOnInit() { }

  getAppVersion() {
    this.appVersion.getVersionNumber().then(version => {
      this.AppVersion = version;
      console.log('当前APP版本', this.AppVersion);
    });
  }


  // 检查app版本更新
  async checkAppUpdate(isCheck) {
    this.loading = await this.loadingCtrl.create({
      spinner: 'bubbles',
      message: `正在检查更新...`,
      cssClass: 'update-loading'
    });
    if (isCheck) {
      this.loading.message = '正在检查更新...';
      this.loading.present();
    };
    const serviceAddr = this.cache.getUrl(101, 100000).serviceAddr;
    const fileUrl = {
      'http://192.168.1.37:8899': 'efos3.0-Test',
      'http://192.168.1.34:8899': 'efos3.0-Test',
      'http://test.api.eegrid.com': 'efos3.0-Beta',
      'http://clientapi.eegrid.com': 'efos3.0',
    }
    this.appUpdate.checkAppUpdate(`http://www.eegrid.com/app/${fileUrl[serviceAddr]}/update.xml`).then(data => {
      console.log('检查版本更新内容', data);
      setTimeout(async () => {
        this.loading.dismiss();
        if (data.localversion < data.version) {
          console.log('有版本更新，无需热更新');
          if (isCheck) {
            setTimeout(async () => {
              this.isUpdate(data);
            });
          } else {
            this.isUpdate(data);
          }
        } else {
          console.log('已经是最新版本');
          if (isCheck) {
            this.alert = await this.alertController.create({
              message: '已经是最新版本',
              cssClass: 'update-alert'
            });
            this.alert.present();
            setTimeout(() => {
              this.alert.dismiss();
            }, 2000)
          } else {
            console.log('无版本更新，检查热更新');
            this.checkUpdate();
          }
        }
      }, 2000)
    })
  }

// 判断是否存在更新
async isUpdate(data) {
  this.updateModal = await this.modalCtrl.create({
    component: UpdateModal,
    componentProps: { updateMenus: data.describe }
  });
  // this.updateModal.componentProps = { updateMenus: data.describe };
  this.updateModal.present();
  const upDate = await this.updateModal.onDidDismiss();
  if (upDate.data) {
    this.downloadApp(data.url);
  } else {
    return;
  }
}

// 进行版本更新下载
async downloadApp(downloadUrl) {
  this.loading = await this.loadingCtrl.create({
    spinner: 'bubbles',
    message: `开始更新...`,
    cssClass: 'update-loading'
  });
  this.loading.message = '开始更新...';
  this.loading.present();
  setTimeout(() => {
    // 下载apk
    const targetUrl = downloadUrl;
    const fileTransfer: FileTransferObject = this.transfer.create();

    fileTransfer.download(targetUrl, this.file.dataDirectory + 'EFOS_3.0.apk').then((entry) => {
      // 下载完成调用打开应用
      setTimeout(() => {
        this.loading.dismiss();
        this.fileOpener.open(entry.toURL(),
          'application/vnd.android.package-archive')
          .then(() => {
            console.log('File is opened');
          })
          .catch(e => {
            console.log('Error openening file', e);
          });
      }, 2000);
    }, (error) => {
      alert(JSON.stringify(error));
    });

    // 获取下载进度
    fileTransfer.onProgress((event) => {
      const num = Math.ceil(event.loaded / event.total * 100);  // 转化成1-100的进度
      if (num === 100) {
        this.loading.message = `更新完成`;
      } else {
        this.loading.message = `正在更新` + num + `%`;
      }
    });
  }, 2000)
}


/**
 * 检查app热更新
 */
async checkUpdate() {

  this.codePush.notifyApplicationReady().then((res) => {
    console.log('告知服务器热更新已成功', res);
  }).catch((error) => {
    console.log('告知服务器更新失败', error);
  });
  this.load = await this.loadingCtrl.create({
    spinner: 'bubbles',
    message: `正在更新`,
    cssClass: 'update-loading'
  });
  if (!this.isMobile()) {
    return;
  }
  let deploymentKey = '';
  if (this.isAndroid() && DEBUG.IS_DEBUG) {
    deploymentKey = CODE_PUSH_DEPLOYMENT_KEY.ANDROID.Staging;
  }
  if (this.isAndroid() && !DEBUG.IS_DEBUG) {
    deploymentKey = CODE_PUSH_DEPLOYMENT_KEY.ANDROID.Production;
  }
  if (this.isIos() && DEBUG.IS_DEBUG) {
    deploymentKey = CODE_PUSH_DEPLOYMENT_KEY.IOS.Staging;
  }
  if (this.isIos() && !DEBUG.IS_DEBUG) {
    deploymentKey = CODE_PUSH_DEPLOYMENT_KEY.IOS.Production;
  }
  this.codePush.getCurrentPackage().then(Package => {
    console.log('当前存在的热更新安装包', Package);
    if (Package) {
      this.cache.edition = { appVersion: Package.appVersion, label: Package.label };
    }
    this.codePush.checkForUpdate(deploymentKey).then(async data => {
      if (data) {
        console.log('当前版本及推送热更新版本', this.AppVersion, data.appVersion);
        console.log('存在热更新及缓存热更新', data, this.cache.edition);
        if (!Package) {
          if (!this.cache.edition) {
            if (parseInt(this.AppVersion, 10) === parseInt(data.appVersion, 10)) {
              console.log('无缓存热更新，且本地版本号与推送版本号相同，赋值后进行更新');
              this.cache.edition = { appVersion: data.appVersion, label: data.label };
              this.isHotApdate(this.cache.edition, data, true);
            } else {
              console.log('无缓存热更新，且本地版本号与推送版本号不同，不进行更新');
            }
          } else {
            if (parseInt(this.cache.edition.appVersion, 10) !== parseInt(data.appVersion, 10)) {
              console.log('有缓存热更新，且缓存版本号与推送版本号不同，重新赋值后进行更新');
              this.cache.edition = { appVersion: data.appVersion, label: data.label };
              this.isHotApdate(this.cache.edition, data, true);
            } else {
              console.log('有缓存热更新，且缓存版本号与推送版本号相同，直接进行更新');
              this.isHotApdate(this.cache.edition, data, true);
            }
          }
        } else {
          this.isHotApdate(this.cache.edition, data, false);
        }
      } else {
        console.log('暂无热更新');
      }
    }, error => {
      console.log('热更新报错');
    });
  }).catch(error => {
    console.log('当前安装包error', error);
  })

}

// 是否进行热更新
isHotApdate(local, data, isFirst) {
  const localLabel = parseInt(local.label.replace('v', ''), 10);
  const dataLabel = parseInt(data.label.replace('v', ''), 10);
  console.log('当前热更新版本', localLabel);
  console.log('发现热更新版本', dataLabel);
  // 比较热更新版本
  if (isFirst) {
    console.log('本地版本等于推送版本，执行初始化更新');
    this.toUpload(data, true);
  } else {
    if (localLabel < dataLabel) {
      console.log('本地版本低于推送版本，执行更新处理');
      this.load.present();
      this.toUpload(data, false);
    } else {
      console.log('版本相同，不做更新处理');
    }
  }
}

// 进行热更新下载
async toUpload(data, isFirst) {
  data.download((success) => {
    success.install(mode => {
      this.load.dismiss();
    }, error => {
      console.log(error);
      this.load.dismiss();
    }, { installMode: isFirst ? InstallMode.ON_NEXT_RESUME : InstallMode.IMMEDIATE })
  }, error => {
    console.log('更新失败', error);
    this.load.dismiss();
  }, progress => {
    const downloadProgress = parseInt(
      ((progress.receivedBytes / progress.totalBytes) * 100).toString(),
      10
    );
    if (!isFirst) {
      console.log(`正在更新 ${downloadProgress}%`);
      this.load.message = `正在更新 ${downloadProgress}%`;
    } else {
      console.log(`初始化更新 ${downloadProgress}%`);
    }
  });
}

isMobile(): boolean {
  return this.platform.is('mobile') && !this.platform.is('mobileweb');
}

isAndroid(): boolean {
  return this.isMobile() && this.platform.is('android');
}

isIos(): boolean {
  return this.isMobile && (this.platform.is('ios') || this.platform.is('ipad') || this.platform.is('iphone'));
}

}
